/**
 * 
 */
package co.edu.javeriana.monopoly.client;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.List;
import java.util.Properties;

import javax.swing.JOptionPane;

import co.edu.javeriana.fw.comunicacion.AddressMachine;
import co.edu.javeriana.fw.comunicacion.IServicios;
import co.edu.javeriana.fw.comunicacion.Peer;
import co.edu.javeriana.monopoly.client.gui.GUI_Client;
import co.edu.javeriana.monopoly.server.eventos.AdicionarJugador;
import co.edu.javeriana.monopoly.server.modelo.IServer;
import co.edu.javeriana.monopoly.server.modelo.Jugada;
import co.edu.javeriana.monopoly.server.modelo.Jugador;
import co.edu.javeriana.monopoly.server.modelo.MonopolyException;
import co.edu.javeriana.monopoly.server.modelo.Tablero;

/**
 * @author lhyna
 *
 */
public class Cliente extends Peer {
    /**
	 * @param args
	 * @throws RemoteException 
	 */
	public static void main ( String[] args ) throws RemoteException {
		Cliente c = new Cliente ( );
	}
	private String address;
	private int clientPort;
	private GUI_Client gui;
	private IServer monopolyServer;
	private String serverAddress;

    private int serverPort;

	public Cliente ( ) throws RemoteException {
		super ( );
		String nombre;
		nombre = JOptionPane.showInputDialog ( "Ingrese su nombre" );
		cargarDatosConexion ( );
		registrarse ( nombre );
		try {
			initCliente ( );
			registerIntoServer ( );
		} catch ( RemoteException e ) {
			e.printStackTrace ( );
			System.out.println ( "Error en la comunicaci�n con el servidor." );
			return;
		}
		gui = new GUI_Client ( this );
		gui.setTitle ( gui.getTitle ( ) + " Partida Activa - " + nombre );
		gui.setVisible ( true );
	}

	private void cargarDatosConexion ( ) {
	    serverPort = 0;
	    clientPort = 0; 
	    Properties properties = new Properties ( );
    	try {
    		properties.load ( new FileInputStream ( "conexion.properties" ) );
    	    serverPort = Integer.parseInt ( properties.getProperty ( "serverPort" ) );
    	    clientPort = Integer.parseInt ( properties.getProperty ( "clientPort" ) );
    	} catch (IOException e) {
    		System.out.println ( "No se encontr� archivo de configuraci�n de conexi�n" );
    	}
       serverAddress = properties.getProperty ( "serverAddress" );
	}

	public void enviarNotificacion ( Jugada jugada ) {
	    if ( System.getSecurityManager ( ) == null ) {
	        System.setSecurityManager ( new RMISecurityManager ( ) );
	    }
	    try {
	        String name = "rmi://" + serverAddress + ":" + serverPort + "/IServicios";
	        IServicios servicio = (IServicios) Naming.lookup ( name );
	        servicio.recibirEvento ( jugada );
	        
	        
	    } catch ( Exception e ) {         
	        System.err.println ( " exception: " + e.getMessage ( ) );
	        e.printStackTrace ( );
	    }
	}

	public void enviarNotificacion ( Object jugada ) {
	    enviarNotificacion ( (Jugada)jugada );
	}

	public void enviarNotificacion ( Object jugada, List jugadores ) {
	}

	public void enviarNotificacion ( Object jugada, Object jugador ) {
	}

	public void initCliente  ( ) throws RemoteException {
        try {
           address = InetAddress.getLocalHost ( ).toString ( );
        } catch ( Exception e ) {
            throw new RemoteException ( "No se puede obtener la direcci�n." );
        }
        System.out.println ( "Monopoly Client=" + address + ", port=" + clientPort );
        try {
            Registry registry = LocateRegistry.createRegistry ( clientPort );
            registry.rebind ( "monopolyClient", this );
        } catch ( RemoteException e ) {
            throw e;
        }
	}

	public void pintarJugada ( Tablero t ) throws RemoteException {
		
	}

	public Jugada recibirEvento ( Jugada jugada ) throws RemoteException, MonopolyException{
	    return new Jugada ( );
	}

	public Object recibirEvento(Object jugada) throws RemoteException {
	    try {
	        return (Jugada)recibirEvento((Jugada)jugada);
	    }catch ( MonopolyException me ) {
	        me.printStackTrace ( );
	        throw new RemoteException ( "", me );
	    }
	}

	public void registerIntoServer ( ) {
	       Registry registry;
	       int serverPort = 0;
	    	Properties properties = new Properties ( );
	    	try {
	    		properties.load ( new FileInputStream ( "conexion.properties" ) );
	    	    serverPort = Integer.parseInt ( properties.getProperty ( "serverPort" ) );
	    	} catch (IOException e) {
	    		System.out.println ( "No se encontr� archivo de configuraci�n de conexi�n" );
	    	}
	       String serverAddress = properties.getProperty ( "serverAddress" );
	       System.out.println ( "Conectando a " + serverAddress + ":" + serverPort );
	       try{
	           registry = LocateRegistry.getRegistry ( serverAddress, serverPort );
	           monopolyServer = (IServer)registry.lookup ( "MonopolyServer" ) ;
	           monopolyServer.adicionarCliente ( address, clientPort );
	       }
	       catch ( RemoteException e ){
	           e.printStackTrace ( );
	       } 
	       catch ( NotBoundException e ){
	           e.printStackTrace ( );
	       }
	}

	public void registrarse ( String nombre ){
	    Jugada jugada = new Jugada ( );
	    AdicionarJugador adicionarjugador = new AdicionarJugador ( null );
	    Jugador j = new Jugador ( );
	    j.setNombre ( nombre );
	    j.setId ( 1 );
	    jugada.setJugador ( j );
	    jugada.setRegla ( adicionarjugador );
	    AddressMachine m = new AddressMachine ( );
	    m.setNameMachine ( address );
	    m.setIp ( address );
	    m.setPortToRecieveRMI ( clientPort );
	    j.setMachine ( m );
	    Object[] objects = new Object[] { j };
	    adicionarjugador.setObjects ( objects );
	    enviarNotificacion ( jugada );
	}
}
